#include "GPIO.h"

bool is_gpios_init = false;
bool is_gpiob_i2c_init = false;

void delay_us(uint16_t time)
{
    uint8_t i;
    for (i = 0; i < 1 * time; i++)
        ;
}

// bool GPIOs_Init(void)
// {
//     GPIO_InitTypeDef *GPIO_InitStruct;
//     if (is_gpios_init)
//     {
//         return true;
//     }

//     GPIO_InitStruct = malloc(sizeof(GPIO_InitTypeDef));

//     // Init GPIO A

//     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

//     GPIO_InitStruct->GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
//     GPIO_InitStruct->GPIO_Pin |= GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_15;
//     GPIO_InitStruct->GPIO_Speed = GPIO_Speed_2MHz;
//     GPIO_InitStruct->GPIO_Mode = GPIO_Mode_Out_PP;
//     GPIO_Init(GPIOA, GPIO_InitStruct);

//     // Init GPIO B

//     if (!is_gpiob_i2c_init)
//     {
//         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
//     }

//     GPIO_InitStruct->GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
//     GPIO_Init(GPIOB, GPIO_InitStruct);

//     // free

//     free(GPIO_InitStruct);

//     // Check set or not
//     // 1.Check RCC_APB2ENR is xxxxxxxx xxxxxxxx xxxxxxxx xxxx11xx or not
//     is_gpios_init = IS_BIT_1(RCC->APB2ENR, BITS(2, 3));

//     // 2-1.Check GPIOA_CRL is 0010 0010 0010 0010 xxxx xxxx 0010 0010 or not

//     is_gpios_init = is_gpios_init && IS_BIT_1(GPIOA->CRL, (BIT(1) | BIT(5) | BIT(17) | BIT(21) | BIT(25) | BIT(29)));
//     is_gpios_init = is_gpios_init && IS_BIT_0(GPIOA->CRL, (BIT(0) | BITS(2, 4) | BITS(6, 7) | BIT(16) | BITS(18, 20) | BITS(22, 24) | BITS(26, 28) | BITS(30, 31)));

//     // 2-2.Check GPIOA_CRH is 0010 xxxx xxxx 0010 0010 0010 0010 0010 or not

//     is_gpios_init = is_gpios_init && IS_BIT_1(GPIOA->CRH, (BIT(1) | BIT(5) | BIT(9) | BIT(13) | BIT(17) | BIT(29)));
//     is_gpios_init = is_gpios_init && IS_BIT_0(GPIOA->CRH, (BIT(0) | BITS(2, 4) | BITS(6, 8) | BITS(10, 12) | BITS(14, 16) | BITS(18, 19) | BIT(28) | BITS(30, 31)));

//     // 2-3.Check GPIOB_CRL is xxxx xxxx 0010 0010 0010 xxxx xxxx xxxx or not

//     is_gpios_init = is_gpios_init && IS_BIT_1(GPIOB->CRH, (BIT(13) | BIT(17) | BIT(21)));
//     is_gpios_init = is_gpios_init && IS_BIT_0(GPIOB->CRH, (BIT(12) | BITS(14, 16) | BITS(18, 20) | BITS(22, 23)));

//     return is_gpios_init;
// }

bool GPIOC_myTest_init(void)
{
    GPIO_InitTypeDef *GPIO_InitStruct;
    GPIO_InitStruct = malloc(sizeof(GPIO_InitTypeDef));

    // Init GPIO C

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

    GPIO_InitStruct->GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStruct->GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_InitStruct->GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOC, GPIO_InitStruct);

    free(GPIO_InitStruct);
    
    GPIOC_myTest_off();

    return (IS_BIT_1(RCC->APB2ENR, BIT(4))) && (IS_BIT_1(GPIOC->CRH, BIT(21))) && (IS_BIT_0(GPIOC->CRH, (BIT(20) | BITS(22, 23))));
}

bool GPIOC_myTest_on(void)
{
    GPIO_ResetBits(GPIOC, GPIO_Pin_13);
    return !GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13);
}

bool GPIOC_myTest_off(void)
{
    GPIO_SetBits(GPIOC, GPIO_Pin_13);
    return GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13);
}
